/* 
 * File:   CSocket.h
 * Author: faraj
 *
 * Created on September 15, 2009, 2:36 AM
 */

#ifndef _CSOCKET_H
#define	_CSOCKET_H

#include "CWrapper.h"
#include "CInetAddress.h"
#include "CFile.h"

class CSocket
{
private:
    int sockfd;
    CInetAddress *address;
    bool connected; 
    
public:
    
    CSocket(string address, int port)
    {
        this->address = new CInetAddress(address,port);
        if(!this->address->havingError())
        {
            this->sockfd = Socket(AF_INET,SOCK_STREAM,0);
            connected = Connect(sockfd,this->address->getSockaddr(),
            sizeof(*this->address->getSockaddr_in()));
        }
        else
        {
            connected = false;
        }
    }
    
    bool isConnected()
    {
        return connected;
    }
    
    CSocket(int sockfd,CInetAddress* addr)
    {
        this->address = addr;
        this->sockfd = sockfd;  
        connected = true;
    }
    
    bool closeSocket()
    {
        this->connected = false;
        return (close(this->sockfd) >= 0);
    }
    
    int getSockfd()
    {
        return sockfd;
    }
    
    bool write(string data)
    {
        Writen(this->sockfd,data.c_str(),data.size());
    }
    
    bool writeln(string data)
    {
        data.push_back('\n');
        return this->write(data);
    }
    
    int writeBytes(const char *data,int len)
    {
        return writen(this->sockfd,data,len);
    }
    
    int readBytes(char *data, int len)
    {
        return Readn(this->sockfd,data,len);
    }
    
    bool sendFile(string sPath)
    {
        int size = getFileSize(sPath);
        
        CFile *file = new CFile(sPath);
        
        if(!file->generateStreams(true,false))
            return false;
        
        ifstream *in = file->getReadStream();
     
        cout << "size is " << size << endl;
        in->seekg (0, ios::beg);
        
        char *memblock = new char [1024];
        int totlen = 0, len = 0;
        
        while(totlen < size)
        {
            
            in->read (memblock, sizeof(*memblock));
            len = in->gcount();
            writeBytes(memblock,len);
            totlen += len;
        }
        
        return file->closeStreams(true,false);
    }
    
    CFile* getFile(string dPath, int size)
    {
        
        char *buff = new char[1024];
        CFile *file = new CFile(dPath);
        
        if(!file->generateStreams(false,true))
            return NULL;
        
        ofstream *out = file->getWriteStream();
        
        int len = 0, totlen = 0;
        
        while(totlen < size)
        {
            len = readBytes(buff,sizeof(*buff));
            totlen += len;
            out->write(buff,len);
        }
        file->closeStreams(false,true);
        return file;
    }
    
    string* read(int length)
    {
        char buff[length];
        Readn(this->sockfd,&buff,sizeof(buff));
        return new string(buff);
    }
    
    string* readln()
    {
        char buff[1024];
        if(Readline(this->sockfd,&buff,sizeof(buff)) <= 0)
            return NULL;
        return new string(buff);
    }
    
    CInetAddress* getAddress()
    {
        return this->address;
    }
};

#endif	/* _CSOCKET_H */

